﻿
#include "ctp_api_trader.h"
#include <filesystem>
#include <time_utils.hpp>

// ctp_api_trader 构造函数
// 参数:
// - id_excg_map: 一个包含交易所 ID 映射的共享指针
// - config: 包含配置参数的对象
ctp_api_trader::ctp_api_trader(const std::shared_ptr<std::unordered_map<std::string, std::string>>& id_excg_map, const params& config) noexcept
    : asyn_actual_trader(id_excg_map) // 调用基类 asyn_actual_trader 的构造函数
    , _td_api(nullptr)               // 初始化指向交易 API 的指针为 nullptr
    , _reqid(0)                      // 初始化请求 ID 为 0
    , _front_id(0)                   // 初始化前置 ID 为 0
    , _session_id(0)                 // 初始化会话 ID 为 0
    , _order_ref(0)                  // 初始化订单引用号为 0
    , _is_runing(false)              // 初始化运行状态为 false
    , _process_mutex(_mutex)         // 初始化处理互斥量
    , _is_inited(false)              // 初始化是否初始化标志为 false
    , _is_connected(false)           // 初始化连接状态标志为 false
    , _is_sync_wait(false)           // 初始化同步等待标志为 false
    , _trader_handle(nullptr)        // 初始化交易句柄为 nullptr
    , _is_in_query(false)            // 初始化查询状态标志为 false
{
    try {
        // 从配置对象中获取必要的参数，失败则捕获异常
        _front_addr = config.get<std::string>("front");      // 获取前置地址
        _broker_id = config.get<std::string>("broker");      // 获取经纪商 ID
        _userid = config.get<std::string>("userid");         // 获取用户 ID
        _password = config.get<std::string>("passwd");       // 获取用户密码
        _appid = config.get<std::string>("appid");           // 获取应用 ID
        _authcode = config.get<std::string>("authcode");     // 获取认证码
        _product_info = config.get<std::string>("product");  // 获取产品信息
    }
    catch (...) {
        // 捕获所有异常并记录错误日志
        LOG_ERROR("ctp_api_trader config error ");
    }

    // 加载交易 API 动态链接库
    _trader_handle = dll_helper::load_library("thosttraderapi_se");
    if (_trader_handle) {
        // 根据平台选择合适的创建 API 函数名称
#ifdef _WIN32
#   ifdef _WIN64
        const char* creator_name = "?CreateFtdcTraderApi@CThostFtdcTraderApi@@SAPEAV1@PEBD@Z"; // Windows 64 位
#   else
        const char* creator_name = "?CreateFtdcTraderApi@CThostFtdcTraderApi@@SAPAV1@PBD@Z";   // Windows 32 位
#   endif
#else
        const char* creator_name = "_ZN19CThostFtdcTraderApi19CreateFtdcTraderApiEPKc";        // 其他平台（如 Linux）
#endif
        // 获取创建交易 API 的函数指针
        _ctp_creator = (trader_creator)dll_helper::get_symbol(_trader_handle, creator_name);
    } else {
        // 如果加载动态库失败，则记录错误日志
        LOG_ERROR("ctp_api_trader thosttraderapi_se load error ");
    }
}


ctp_api_trader::~ctp_api_trader() noexcept
{
    // 释放加载的动态库
    dll_helper::free_library(_trader_handle);
    
    // 将 _trader_handle 置为 nullptr，避免悬空指针
    _trader_handle = nullptr;
}

// ctp_api_trader::login() 方法
// 功能：初始化 CTP 交易 API 并处理登录流程
// 返回值：总是返回 true，表示登录操作成功
bool ctp_api_trader::login() noexcept
{
    _is_runing = true; // 设置运行状态为 true，表示开始登录流程

    char path_buff[64]; // 定义一个字符数组用于存储流文件路径
    sprintf(path_buff, "td_flow/%s/%s/", _broker_id.c_str(), _userid.c_str()); // 格式化流文件路径，基于经纪商和用户 ID

    // 检查路径是否存在，如果不存在则创建该目录
    if (!std::filesystem::exists(path_buff))
    {
        std::filesystem::create_directories(path_buff); // 创建必要的目录结构
    }

    // 创建交易 API 实例，传入路径用于保存交易流数据
    _td_api = _ctp_creator(path_buff);
    
    // 注册 SPI（事件处理接口），将当前对象作为 SPI 注册到交易 API 中
    _td_api->RegisterSpi(this);

    // 订阅私有和公共主题，设置为快速模式（即获取的市场和交易数据更及时）
    _td_api->SubscribePrivateTopic(THOST_TERT_QUICK); // 订阅私有主题
    _td_api->SubscribePublicTopic(THOST_TERT_QUICK);  // 订阅公共主题

    // 注册前置地址，告诉交易 API 如何连接到交易服务器
    _td_api->RegisterFront(const_cast<char*>(_front_addr.c_str()));

    // 初始化交易 API，开始连接并进入事件处理循环
    _td_api->Init();

    LOG_INFO("ctp_api_trader init "); // 记录日志，表明 API 已经初始化

    // 等待信号以确保初始化过程完成，_process_signal 是一个信号量或条件变量
    _process_signal.wait(_process_mutex);

    _is_inited = true; // 设置初始化标志为 true

    // 提交结算信息确认，该方法可能是处理登录完成后的一个附加操作
    submit_settlement();

    LOG_INFO("ctp_api_trader login"); // 记录日志，表明登录过程完成

    return true; // 总是返回 true，表示登录成功
}


// ctp_api_trader::logout() 方法
// 功能：登出交易系统并清理资源
void ctp_api_trader::logout() noexcept
{
    _is_runing = false; // 设置运行状态为 false，表示停止运行

    do_logout(); // 执行登出操作，通常包括发送登出请求到交易服务器

    _reqid = 0; // 重置请求 ID 为 0

    _front_id = 0; // 重置前置编号，通常用于标识交易系统连接的前置机
    _session_id = 0; // 重置会话编号，用于标识用户的会话

    _order_ref.exchange(0); // 重置报单引用号为 0，使用原子操作以确保线程安全

    _position_info.clear(); // 清空持仓信息的容器，清理所有持仓数据
    _order_info.clear(); // 清空订单信息的容器，清理所有订单数据

    _is_in_query.exchange(false); // 重置查询状态标志为 false，使用原子操作确保线程安全
    _is_inited = false; // 设置初始化标志为 false，表示系统已停止初始化状态
    _is_connected = false; // 设置连接状态为 false，表示已断开连接
    _is_sync_wait.exchange(false); // 重置同步等待标志为 false，确保不会有等待同步的操作在进行

    if (_td_api) // 如果交易 API 实例存在
    {
        _td_api->RegisterSpi(nullptr); // 注销 SPI（事件处理接口），防止后续再调用回调
        // _td_api->Join(); // （已注释）等待事件处理线程结束（如果存在）
        _td_api->Release(); // 释放交易 API 实例，清理相关资源
        _td_api = nullptr; // 将 API 指针置为 nullptr，避免悬空指针
    }

    LOG_INFO("ctp_api_trader logout"); // 记录日志，表明登出过程已完成
}

// ctp_api_trader::do_login() 方法
// 功能：向 CTP 交易服务器发送登录请求
// 返回值：成功发送请求返回 true，失败则返回 false
bool ctp_api_trader::do_login() noexcept
{
    // 检查交易 API 对象是否为空，如果为空则无法登录
    if (_td_api == nullptr)
    {
        return false; // 交易 API 未初始化，直接返回 false
    }

    // 定义登录请求结构体并初始化为 0
    CThostFtdcReqUserLoginField req;
    memset(&req, 0, sizeof(req)); // 使用 memset 将结构体内存清零

    // 设置登录请求的各项参数
    strcpy(req.BrokerID, _broker_id.c_str());        // 设置经纪商 ID
    strcpy(req.UserID, _userid.c_str());             // 设置用户 ID
    strcpy(req.Password, _password.c_str());         // 设置用户密码
    strcpy(req.UserProductInfo, _product_info.c_str()); // 设置用户产品信息

    // 发送用户登录请求，调用交易 API 的 ReqUserLogin 方法
    // 传入登录请求结构体和请求 ID
    int iResult = _td_api->ReqUserLogin(&req, genreqid());

    // 检查请求结果，非 0 表示请求失败
    if (iResult != 0)
    {
        // 记录错误日志，显示登录请求失败和错误代码
        LOG_ERROR("ctp_api_trader do_login request failed:", iResult);
        return false; // 返回 false 表示登录请求失败
    }

    return true; // 登录请求成功发送，返回 true
}


// ctp_api_trader::do_logout() 方法
// 功能：向 CTP 交易服务器发送登出请求
// 返回值：如果请求发送成功返回 true，发送失败返回 false
bool ctp_api_trader::do_logout() noexcept
{
    // 检查交易 API 对象是否为空，如果为空则无法进行登出操作
    if (_td_api == nullptr)
    {
        return false; // 交易 API 未初始化，返回 false
    }

    // 定义用户登出请求结构体并初始化为 0
    CThostFtdcUserLogoutField req;
    memset(&req, 0, sizeof(req)); // 使用 memset 将结构体清零

    // 设置登出请求的参数
    strcpy(req.BrokerID, _broker_id.c_str()); // 将经纪商 ID 复制到登出请求结构体的 BrokerID 字段
    strcpy(req.UserID, _userid.c_str());      // 将用户 ID 复制到登出请求结构体的 UserID 字段

    // 发送用户登出请求，调用交易 API 的 ReqUserLogout 方法
    // 传入登出请求结构体和请求 ID
    int iResult = _td_api->ReqUserLogout(&req, genreqid());

    // 检查请求结果，非 0 表示请求发送失败
    if (iResult != 0)
    {
        // 记录错误日志，显示登出请求失败的错误代码
        LOG_ERROR("ctp_api_trader logout request failed:", iResult);
        return false; // 返回 false，表示登出请求失败
    }

    return true; // 请求发送成功，返回 true
}

// ctp_api_trader::query_positions() 方法
// 功能：向 CTP 交易服务器发送查询持仓请求，并根据参数决定是否同步等待查询结果
// 参数：is_sync - 如果为 true，表示需要同步等待查询结果；如果为 false，则异步查询
// 返回值：如果请求发送成功返回 true，失败返回 false
bool ctp_api_trader::query_positions(bool is_sync) noexcept
{
    // 检查交易 API 对象是否为空，如果为空则无法进行查询操作
    if (_td_api == nullptr)
    {
        return false; // 交易 API 未初始化，返回 false
    }

    bool expected = false; // 用于检查查询状态的期望值
    // 使用 compare_exchange_weak 尝试将 _is_in_query 设置为 true，以表示当前处于查询状态
    if (!_is_in_query.compare_exchange_weak(expected, true))
    {
        // 如果 _is_in_query 已经是 true，则表示正在查询中，记录错误日志
        LOG_ERROR("ctp trader _is_in_query not return");
        return false; // 返回 false，表示无法进行新的查询
    }

    // 定义投资者持仓查询请求结构体并初始化为 0
    CThostFtdcQryInvestorPositionField req;
    memset(&req, 0, sizeof(req)); // 使用 memset 将结构体清零

    // 设置查询请求的参数
    strcpy(req.BrokerID, _broker_id.c_str());  // 将经纪商 ID 复制到请求结构体的 BrokerID 字段
    strcpy(req.InvestorID, _userid.c_str());   // 将用户 ID 复制到请求结构体的 InvestorID 字段

    // 发送投资者持仓查询请求，调用交易 API 的 ReqQryInvestorPosition 方法
    // 传入持仓查询请求结构体和请求 ID
    auto iResult = _td_api->ReqQryInvestorPosition(&req, genreqid());

    // 检查请求结果，非 0 表示请求发送失败
    if (iResult != 0)
    {
        // 记录错误日志，显示持仓查询请求失败的错误代码
        LOG_ERROR("ReqQryInvestorPosition failed:", iResult);
        // 将查询状态 _is_in_query 重置为 false，确保状态正确
        while (!_is_in_query.exchange(false));
        return false; // 返回 false，表示查询请求失败
    }

    // 如果需要同步等待查询结果
    if (is_sync)
    {
        // 将同步等待状态 _is_sync_wait 设置为 true，确保当前在等待状态
        while (!_is_sync_wait.exchange(true));
        // 等待查询结果完成，_process_signal 是一个信号量或条件变量
        _process_signal.wait(_process_mutex);
    }

    return true; // 请求发送成功，返回 true
}



// ctp_api_trader::query_orders() 方法
// 功能：向 CTP 交易服务器发送查询订单请求，并根据参数决定是否同步等待查询结果
// 参数：is_sync - 如果为 true，表示需要同步等待查询结果；如果为 false，则异步查询
// 返回值：如果请求发送成功返回 true，发送失败返回 false
bool ctp_api_trader::query_orders(bool is_sync) noexcept
{
    // 检查交易 API 对象是否为空，如果为空则无法进行查询操作
    if (_td_api == nullptr)
    {
        return false; // 交易 API 未初始化，返回 false
    }

    bool expected = false; // 用于检查查询状态的期望值
    // 使用 compare_exchange_weak 尝试将 _is_in_query 设置为 true，以表示当前处于查询状态
    if (!_is_in_query.compare_exchange_weak(expected, true))
    {
        // 如果 _is_in_query 已经是 true，则表示正在查询中，记录错误日志
        LOG_ERROR("ctp mini trader _is_in_query not return");
        return false; // 返回 false，表示无法进行新的查询
    }

    // 定义订单查询请求结构体并初始化为 0
    CThostFtdcQryOrderField req;
    memset(&req, 0, sizeof(req)); // 使用 memset 将结构体清零

    // 设置查询请求的参数
    strcpy(req.BrokerID, _broker_id.c_str());  // 将经纪商 ID 复制到请求结构体的 BrokerID 字段
    strcpy(req.InvestorID, _userid.c_str());   // 将用户 ID 复制到请求结构体的 InvestorID 字段

    // 发送订单查询请求，调用交易 API 的 ReqQryOrder 方法
    // 传入订单查询请求结构体和请求 ID
    auto iResult = _td_api->ReqQryOrder(&req, genreqid());

    // 检查请求结果，非 0 表示请求发送失败
    if (iResult != 0)
    {
        // 记录错误日志，显示订单查询请求失败的错误代码
        LOG_ERROR("ReqQryOrder failed:", iResult);
        // 将查询状态 _is_in_query 重置为 false，确保状态正确
        while (!_is_in_query.exchange(false));
        return false; // 返回 false，表示查询请求失败
    }

    // 如果需要同步等待查询结果
    if (is_sync)
    {
        // 将同步等待状态 _is_sync_wait 设置为 true，确保当前在等待状态
        while (!_is_sync_wait.exchange(true));
        // 等待查询结果完成，_process_signal 是一个信号量或条件变量
        _process_signal.wait(_process_mutex);
    }

    return true; // 请求发送成功，返回 true
}



// ctp_api_trader::OnFrontConnected() 方法
// 功能：处理前置服务器连接成功的事件回调
// 返回值：无
void ctp_api_trader::OnFrontConnected() noexcept
{
    // 记录日志，表示前置服务器已经成功连接
    LOG_INFO("ctp_api_trader OnFrontConnected");

    // 设置连接状态为 true，表示当前已成功连接到前置服务器
    _is_connected = true;

    // 检查是否处于运行状态
    if (_is_runing)
    {
        // 如果处于运行状态，执行认证操作
        do_auth(); // 调用认证方法进行后续的认证流程
    }
}



// ctp_api_trader::OnFrontDisconnected() 方法
// 功能：处理前置服务器断开连接的事件回调
// 参数：nReason - 表示断开连接的原因代码
// 返回值：无
void ctp_api_trader::OnFrontDisconnected(int nReason) noexcept
{
    // 记录日志，显示前置服务器断开连接的原因代码
    LOG_INFO("ctp_api_trader FrontDisconnected : Reason ->", nReason);

    // 设置连接状态为 false，表示当前已断开与前置服务器的连接
    _is_connected = false;
}


// ctp_api_trader::OnRspAuthenticate() 方法
// 功能：处理认证响应的回调事件，当收到服务器的认证响应时被调用
// 参数：
// - pRspAuthenticateField: 指向认证响应信息结构体的指针，包含认证相关信息
// - pRspInfo: 指向响应信息结构体的指针，包含错误代码和错误信息
// - nRequestID: 请求 ID，用于匹配请求与响应
// - bIsLast: 是否为最后一条响应，true 表示是最后一条
// 返回值：无
void ctp_api_trader::OnRspAuthenticate(CThostFtdcRspAuthenticateField *pRspAuthenticateField, 
                                       CThostFtdcRspInfoField *pRspInfo, 
                                       int nRequestID, 
                                       bool bIsLast) noexcept
{
    // 检查响应信息 pRspInfo 是否存在，以及是否存在错误
    if (pRspInfo && pRspInfo->ErrorID)
    {
        // 记录错误日志，显示认证错误的错误代码和错误信息
        LOG_ERROR("ctp_api_trader OnRspAuthenticate Error :", pRspInfo->ErrorID, pRspInfo->ErrorMsg);
        return; // 发生错误时退出，不执行后续的登录操作
    }

    // 如果认证成功，执行登录操作
    do_login(); // 调用登录方法进行后续的登录流程
}

// ctp_api_trader::OnRspUserLogin() 方法
// 功能：处理用户登录响应的回调事件，当收到服务器的用户登录响应时被调用
// 参数：
// - pRspUserLogin: 指向用户登录响应信息结构体的指针，包含用户登录的详细信息
// - pRspInfo: 指向响应信息结构体的指针，包含错误代码和错误信息
// - nRequestID: 请求 ID，用于匹配请求与响应
// - bIsLast: 是否为最后一条响应，true 表示是最后一条
// 返回值：无
void ctp_api_trader::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, 
                                    CThostFtdcRspInfoField *pRspInfo, 
                                    int nRequestID, 
                                    bool bIsLast) noexcept
{
    // 检查响应信息 pRspInfo 是否存在，以及是否存在错误
    if (pRspInfo && pRspInfo->ErrorID)
    {
        // 记录错误日志，显示用户登录的错误代码和错误信息
        LOG_ERROR("ctp_api_trader OnRspUserLogin Error : ", pRspInfo->ErrorID, pRspInfo->ErrorMsg);
        return; // 发生错误时退出，不执行后续操作
    }

    // 如果用户登录响应信息存在
    if (pRspUserLogin)
    {
        // 记录用户登录的详细信息，包括交易日、登录时间、用户 ID、应用 ID、会话 ID 和前置编号
        LOG_INFO("[%s][用户登录] UserID:%s AppID:%s SessionID:%d FrontID:%d",
            datetime_to_string(pRspUserLogin->TradingDay, pRspUserLogin->LoginTime).c_str(), // 格式化交易日和登录时间
            pRspUserLogin->UserID, // 显示用户 ID
            _appid.c_str(), // 显示应用 ID
            pRspUserLogin->SessionID, // 显示会话 ID
            pRspUserLogin->FrontID); // 显示前置编号

        // 保存会话相关的参数，便于后续操作使用
        _front_id = pRspUserLogin->FrontID; // 保存前置编号
        _session_id = pRspUserLogin->SessionID; // 保存会话编号
        _order_ref = atoi(pRspUserLogin->MaxOrderRef); // 将最大订单引用号转换为整数并保存
    }

    // 如果这是最后一条响应且尚未初始化
    if (bIsLast && !_is_inited)
    {
        // 通知所有等待的线程，初始化过程已经完成
        _process_signal.notify_all();
    }
}



// ctp_api_trader::OnRspUserLogout() 方法
// 功能：处理用户登出响应的回调事件，当收到服务器的用户登出响应时被调用
// 参数：
// - pUserLogout: 指向用户登出响应信息结构体的指针，包含用户登出时的详细信息
// - pRspInfo: 指向响应信息结构体的指针，包含错误代码和错误信息
// - nRequestID: 请求 ID，用于匹配请求与响应
// - bIsLast: 是否为最后一条响应，true 表示是最后一条
// 返回值：无
void ctp_api_trader::OnRspUserLogout(CThostFtdcUserLogoutField *pUserLogout, 
                                     CThostFtdcRspInfoField *pRspInfo, 
                                     int nRequestID, 
                                     bool bIsLast) noexcept
{
    // 检查响应信息 pRspInfo 是否存在
    if (pRspInfo)
    {
        // 记录登出过程中的响应信息，包括错误代码和错误消息
        LOG_DEBUG("UserLogout : %d -> %s", pRspInfo->ErrorID, pRspInfo->ErrorMsg);
    }
}


// ctp_api_trader::OnRspSettlementInfoConfirm() 方法
// 功能：处理结算信息确认响应的回调事件，当收到服务器的结算信息确认响应时被调用
// 参数：
// - pSettlementInfoConfirm: 指向结算信息确认响应结构体的指针，包含结算信息的确认详情
// - pRspInfo: 指向响应信息结构体的指针，包含错误代码和错误信息
// - nRequestID: 请求 ID，用于匹配请求与响应
// - bIsLast: 是否为最后一条响应，true 表示是最后一条
// 返回值：无
void ctp_api_trader::OnRspSettlementInfoConfirm(CThostFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, 
                                                CThostFtdcRspInfoField *pRspInfo, 
                                                int nRequestID, 
                                                bool bIsLast) noexcept
{
    // 检查响应信息 pRspInfo 是否存在，以及是否存在错误
    if (pRspInfo && pRspInfo->ErrorID != 0)
    {
        // 记录错误日志，显示结算信息确认的错误代码和错误消息
        LOG_DEBUG("OnRspSettlementInfoConfirm\tErrorID =", pRspInfo->ErrorID, "ErrorMsg =", pRspInfo->ErrorMsg);
    }

    // 检查是否为最后一条响应
    if (bIsLast)
    {
        // 通知所有等待的线程，表明结算信息确认过程已完成
        _process_signal.notify_all();
    }
}


// ctp_api_trader::OnRspOrderInsert() 方法
// 功能：处理订单插入（下单）响应的回调事件，当收到服务器的订单插入响应时被调用
// 参数：
// - pInputOrder: 指向订单插入请求信息结构体的指针，包含订单的详细信息
// - pRspInfo: 指向响应信息结构体的指针，包含错误代码和错误信息
// - nRequestID: 请求 ID，用于匹配请求与响应
// - bIsLast: 是否为最后一条响应，true 表示是最后一条
// 返回值：无
void ctp_api_trader::OnRspOrderInsert(CThostFtdcInputOrderField *pInputOrder, 
                                      CThostFtdcRspInfoField *pRspInfo, 
                                      int nRequestID, 
                                      bool bIsLast) noexcept
{
    // 检查响应信息 pRspInfo 是否存在，以及是否存在错误
    if (pRspInfo && pRspInfo->ErrorID != 0)
    {
        // 记录错误日志，显示订单插入的错误代码和错误消息
        LOG_ERROR("OnRspOrderInsert \tErrorID =", pRspInfo->ErrorID, "ErrorMsg =", pRspInfo->ErrorMsg);
    }

    // 如果订单信息和响应信息都存在
    if (pInputOrder && pRspInfo)
    {
        // 生成扩展订单 ID（estid），用于唯一标识订单
        // 使用前置编号、会话编号和订单引用号生成 estid
        estid_t estid = generate_estid(_front_id, _session_id, strtol(pInputOrder->OrderRef, NULL, 10));

        // 触发订单错误事件，传递订单错误类型和错误代码
        this->fire_event(trader_event_type::TET_OrderError, // 事件类型：订单错误
                         error_type::ET_PLACE_ORDER,       // 错误类型：下单错误
                         estid,                           // 扩展订单 ID
                         (uint8_t)pRspInfo->ErrorID);     // 错误代码
    }
}


// ctp_api_trader::OnRspOrderAction() 方法
// 功能：处理订单操作（如撤单）响应的回调事件，当收到服务器的订单操作响应时被调用
// 参数：
// - pInputOrderAction: 指向订单操作请求信息结构体的指针，包含订单操作的详细信息（如撤单请求）
// - pRspInfo: 指向响应信息结构体的指针，包含错误代码和错误信息
// - nRequestID: 请求 ID，用于匹配请求与响应
// - bIsLast: 是否为最后一条响应，true 表示是最后一条
// 返回值：无
void ctp_api_trader::OnRspOrderAction(CThostFtdcInputOrderActionField *pInputOrderAction, 
                                      CThostFtdcRspInfoField *pRspInfo, 
                                      int nRequestID, 
                                      bool bIsLast) noexcept
{
    // 检查响应信息 pRspInfo 是否存在，以及是否存在错误
    if (pRspInfo && pRspInfo->ErrorID != 0)
    {
        // 记录错误日志，显示订单操作的错误代码和错误消息
        LOG_ERROR("OnRspOrderAction \tErrorID =", pRspInfo->ErrorID, "ErrorMsg =", pRspInfo->ErrorMsg);
    }

    // 如果订单操作信息和响应信息都存在
    if (pInputOrderAction && pRspInfo)
    {
        // 生成扩展订单 ID（estid），用于唯一标识订单
        // 使用订单操作信息中的前置编号、会话编号和订单引用号生成 estid
        estid_t estid = generate_estid(pInputOrderAction->FrontID, pInputOrderAction->SessionID, strtol(pInputOrderAction->OrderRef, NULL, 10));

        // 触发订单错误事件，传递订单操作错误类型（如撤单错误）和错误代码
        this->fire_event(trader_event_type::TET_OrderError, // 事件类型：订单错误
                         error_type::ET_CANCEL_ORDER,      // 错误类型：撤单错误
                         estid,                            // 扩展订单 ID
                         (uint8_t)pRspInfo->ErrorID);      // 错误代码
    }
}



// ctp_api_trader::OnRspQryInvestorPosition() 方法
// 功能：处理投资者持仓查询响应的回调事件，当收到服务器的持仓查询响应时被调用
// 参数：
// - pInvestorPosition: 指向投资者持仓信息结构体的指针，包含持仓的详细信息
// - pRspInfo: 指向响应信息结构体的指针，包含错误代码和错误信息
// - nRequestID: 请求 ID，用于匹配请求与响应
// - bIsLast: 是否为最后一条响应，true 表示是最后一条
// 返回值：无
void ctp_api_trader::OnRspQryInvestorPosition(CThostFtdcInvestorPositionField *pInvestorPosition, 
                                              CThostFtdcRspInfoField *pRspInfo, 
                                              int nRequestID, 
                                              bool bIsLast) noexcept
{
    // 检查查询状态，如果在查询过程中则重置状态并清空持仓信息
    if (_is_in_query)
    {
        while (!_is_in_query.exchange(false)); // 将查询状态重置为 false
        _position_info.clear(); // 清空持仓信息，准备接收新的查询结果
    }

    // 检查响应信息 pRspInfo 是否存在，以及是否存在错误
    if (pRspInfo && pRspInfo->ErrorID != 0)
    {
        // 记录错误日志，显示持仓查询的错误代码和错误消息
        LOG_ERROR("OnRspQryInvestorPosition \tErrorID = [%d] ErrorMsg = [%s]", pRspInfo->ErrorID, pRspInfo->ErrorMsg);
        return; // 发生错误时退出，不执行后续操作
    }

    // 如果持仓信息存在
    if (pInvestorPosition)
    {   
        // 记录持仓的详细信息，包括合约 ID、今日持仓、总持仓和昨持仓
        LOG_DEBUG("OnRspQryInvestorPosition ", pInvestorPosition->InstrumentID, pInvestorPosition->TodayPosition, 
                  pInvestorPosition->Position, pInvestorPosition->YdPosition);

        // 根据合约 ID 和交易所 ID 创建一个持仓代码对象
        code_t code(pInvestorPosition->InstrumentID, pInvestorPosition->ExchangeID);
        position_seed pos; // 定义一个持仓种子对象
        auto it = _position_info.find(code); // 查找当前持仓信息中是否已有该持仓代码的记录

        // 如果找到了该持仓代码的记录，则使用已有的数据
        if (it != _position_info.end())
        {
            pos = it->second;
        }

        // 设置持仓代码
        pos.id = code;

        // 根据持仓方向（多头或空头）更新持仓信息
        if (pInvestorPosition->PosiDirection == THOST_FTDC_PD_Long) // 多头持仓
        {
            // 如果持仓为今日持仓
            if (pInvestorPosition->PositionDate == THOST_FTDC_PSD_Today)
            {
                // 如果持仓代码有区分今日持仓和历史持仓的需求
                if (code.is_distinct())
                {
                    pos.today_long += pInvestorPosition->TodayPosition; // 更新今日多头持仓
                }
                else
                {
                    pos.today_long += pInvestorPosition->Position; // 更新总多头持仓
                }
            }
            else // 历史持仓
            {
                pos.history_long += (pInvestorPosition->Position - pInvestorPosition->TodayPosition); // 更新历史多头持仓
            }
        }
        else if (pInvestorPosition->PosiDirection == THOST_FTDC_PD_Short) // 空头持仓
        {
            // 如果持仓为今日持仓
            if (pInvestorPosition->PositionDate == THOST_FTDC_PSD_Today)
            {
                // 如果持仓代码有区分今日持仓和历史持仓的需求
                if (code.is_distinct())
                {
                    pos.today_short += pInvestorPosition->TodayPosition; // 更新今日空头持仓
                }
                else
                {
                    pos.today_short += pInvestorPosition->Position; // 更新总空头持仓
                }
            }
            else // 历史持仓
            {
                pos.history_short += (pInvestorPosition->Position - pInvestorPosition->TodayPosition); // 更新历史空头持仓
            }
        }

        // 将更新后的持仓信息保存到持仓信息表中
        _position_info[code] = pos;
    }

    // 如果这是最后一条响应且在同步等待状态
    if (bIsLast && _is_sync_wait)
    {
        while (!_is_sync_wait.exchange(false)); // 将同步等待状态重置为 false
        _process_signal.notify_all(); // 通知所有等待的线程，表明持仓查询过程已完成
    }
}


// ctp_api_trader::OnRspQryOrder() 方法
// 功能：处理订单查询响应的回调事件，当收到服务器的订单查询响应时被调用
// 参数：
// - pOrder: 指向订单信息结构体的指针，包含订单的详细信息
// - pRspInfo: 指向响应信息结构体的指针，包含错误代码和错误信息
// - nRequestID: 请求 ID，用于匹配请求与响应
// - bIsLast: 是否为最后一条响应，true 表示是最后一条
// 返回值：无
void ctp_api_trader::OnRspQryOrder(CThostFtdcOrderField *pOrder, 
                                   CThostFtdcRspInfoField *pRspInfo, 
                                   int nRequestID, 
                                   bool bIsLast) noexcept
{
    // 如果当前处于查询状态，则重置查询状态并清空订单信息
    if (_is_in_query)
    {
        while (!_is_in_query.exchange(false)); // 将查询状态重置为 false
        _order_info.clear(); // 清空订单信息，准备接收新的查询结果
    }

    // 检查订单信息是否存在，订单总量是否大于 0，并且订单状态不是已取消或全部成交
    if (pOrder && pOrder->VolumeTotal > 0 && pOrder->OrderStatus != THOST_FTDC_OST_Canceled && pOrder->OrderStatus != THOST_FTDC_OST_AllTraded)
    {
        // 生成扩展订单 ID（estid），用于唯一标识订单
        // 使用订单的前置编号、会话编号和订单引用号生成 estid
        estid_t estid = generate_estid(pOrder->FrontID, pOrder->SessionID, strtoul(pOrder->OrderRef, NULL, 10));

        // 获取或创建订单对象并更新其详细信息
        auto order = _order_info[estid];
        order.code = code_t(pOrder->InstrumentID, pOrder->ExchangeID); // 设置订单的合约代码
        order.create_time = make_daytm(pOrder->InsertTime, 0U); // 设置订单的创建时间
        order.estid = estid; // 设置订单的扩展 ID
        order.direction = wrap_direction_offset(pOrder->Direction, pOrder->CombOffsetFlag[0]); // 设置订单的方向
        order.offset = wrap_offset_type(pOrder->CombOffsetFlag[0]); // 设置订单的开平标志
        order.last_volume = pOrder->VolumeTotal; // 设置订单的剩余数量
        order.total_volume = pOrder->VolumeTotal + pOrder->VolumeTraded; // 设置订单的总数量
        order.price = pOrder->LimitPrice; // 设置订单的价格

        // 将更新后的订单信息保存到订单信息表中
        _order_info[estid] = order;

        // 记录订单的详细信息日志，包括合约代码、扩展 ID、前置编号、会话编号、订单引用号和价格
        LOG_INFO("OnRspQryOrder", pOrder->InstrumentID, estid, pOrder->FrontID, pOrder->SessionID, pOrder->OrderRef, pOrder->LimitPrice);
    }

    // 如果这是最后一条响应且处于同步等待状态
    if (bIsLast && _is_sync_wait)
    {
        while (!_is_sync_wait.exchange(false)); // 将同步等待状态重置为 false
        _process_signal.notify_all(); // 通知所有等待的线程，表明订单查询过程已完成
    }
}



// ctp_api_trader::OnRspError() 方法
// 功能：处理通用错误响应的回调事件，当服务器返回错误响应时被调用
// 参数：
// - pRspInfo: 指向响应信息结构体的指针，包含错误代码和错误信息
// - nRequestID: 请求 ID，用于匹配请求与响应
// - bIsLast: 是否为最后一条响应，true 表示是最后一条
// 返回值：无
void ctp_api_trader::OnRspError(CThostFtdcRspInfoField *pRspInfo, 
                                int nRequestID, 
                                bool bIsLast) noexcept
{
    // 检查系统是否已初始化，如果未初始化则直接返回
    if (!_is_inited)
    {
        return;
    }

    // 检查错误响应信息是否存在
    if (pRspInfo)
    {
        // 记录错误日志，显示错误代码和错误消息
        LOG_ERROR("OnRspError \tErrorID = ", pRspInfo->ErrorID, " ErrorMsg =", pRspInfo->ErrorMsg);

        // 触发错误事件，将错误信息传递给系统的事件处理机制
        this->fire_event(trader_event_type::TET_OrderError, // 事件类型：订单错误
                         error_type::ET_OTHER_ERROR,       // 错误类型：其他错误
                         INVALID_ESTID,                    // 使用无效的订单 ID 表示未关联特定订单
                         (uint8_t)pRspInfo->ErrorID);      // 错误代码
    }
}



// ctp_api_trader::OnRtnOrder() 方法
// 功能：处理订单状态变化的回调事件，当服务器返回订单状态更新时被调用
// 参数：
// - pOrder: 指向订单信息结构体的指针，包含订单的详细信息
// 返回值：无
void ctp_api_trader::OnRtnOrder(CThostFtdcOrderField *pOrder) noexcept
{
    // 如果订单信息不存在或系统未初始化，直接返回
    if (pOrder == nullptr || !_is_inited)
    {
        return;
    }

    // 生成扩展订单 ID（estid），用于唯一标识订单
    auto estid = generate_estid(pOrder->FrontID, pOrder->SessionID, strtoul(pOrder->OrderRef, NULL, 10));
    auto code = code_t(pOrder->InstrumentID, pOrder->ExchangeID); // 生成订单的合约代码
    auto direction = wrap_direction_offset(pOrder->Direction, pOrder->CombOffsetFlag[0]); // 获取订单方向
    auto offset = wrap_offset_type(pOrder->CombOffsetFlag[0]); // 获取开平标志
    auto is_today = (THOST_FTDC_OF_CloseToday == pOrder->CombOffsetFlag[0]); // 检查是否为今日订单

    // 记录订单状态变化的日志
    LOG_INFO("OnRtnOrder", estid, pOrder->FrontID, pOrder->SessionID, pOrder->InstrumentID, direction, offset, pOrder->OrderStatus);

    // 如果订单状态是已取消或全部成交
    if (pOrder->OrderStatus == THOST_FTDC_OST_Canceled || pOrder->OrderStatus == THOST_FTDC_OST_AllTraded)
    {
        // 查找订单信息
        auto it = _order_info.find(estid);
        if (it != _order_info.end())
        {
            auto order = it->second;
            // 计算成交量变化并更新订单剩余量
            if (order.last_volume > static_cast<uint32_t>(pOrder->VolumeTotal))
            {
                uint32_t deal_volume = order.last_volume - pOrder->VolumeTotal;
                order.last_volume = pOrder->VolumeTotal;

                // 触发成交事件，通知订单部分成交
                this->fire_event(trader_event_type::TET_OrderDeal, estid, deal_volume, (uint32_t)(pOrder->VolumeTotal));
            }

            // 如果订单状态是已取消
            if (pOrder->OrderStatus == THOST_FTDC_OST_Canceled)
            {
                // 记录取消事件并触发订单取消事件
                LOG_INFO("OnRtnOrder fire_event ET_OrderCancel", estid, code.get_id(), direction, offset);
                this->fire_event(trader_event_type::TET_OrderCancel, estid, code, offset, direction, pOrder->LimitPrice, 
                                 (uint32_t)pOrder->VolumeTotal, (uint32_t)(pOrder->VolumeTraded + pOrder->VolumeTotal));
            }

            // 如果订单状态是全部成交
            if (pOrder->OrderStatus == THOST_FTDC_OST_AllTraded)
            {
                // 记录成交事件并触发订单成交事件
                LOG_INFO("OnRtnOrder fire_event ET_OrderTrade", estid, code.get_id(), direction, offset);
                this->fire_event(trader_event_type::TET_OrderTrade, estid, code, offset, direction, pOrder->LimitPrice, 
                                 (uint32_t)(pOrder->VolumeTraded + pOrder->VolumeTotal));
            }

            // 从订单信息中删除已处理的订单
            _order_info.erase(it);
        }
    }
    else
    {
        // 查找订单信息，如果未找到则创建新的订单记录
        auto it = _order_info.find(estid);
        if (it == _order_info.end())
        {
            order_info entrust;
            entrust.code = code;
            entrust.create_time = make_daytm(pOrder->InsertTime, 0U);
            entrust.estid = estid;
            entrust.direction = direction;
            entrust.last_volume = pOrder->VolumeTotal;
            entrust.total_volume = pOrder->VolumeTotal + pOrder->VolumeTraded;
            entrust.offset = offset;
            entrust.price = pOrder->LimitPrice;

            // 将新订单加入订单信息表中
            _order_info.insert(std::make_pair(estid, entrust));

            // 触发下单事件
            this->fire_event(trader_event_type::TET_OrderPlace, entrust);

            // 如果订单已部分成交，触发成交事件
            if (pOrder->VolumeTraded > 0)
            {
                this->fire_event(trader_event_type::TET_OrderDeal, estid, (uint32_t)pOrder->VolumeTotal, (uint32_t)(pOrder->VolumeTotal));
            }
        }
        else
        {
            // 更新已存在的订单记录
            auto entrust = it->second;
            // 处理订单成交量的变化
            if (entrust.last_volume > static_cast<uint32_t>(pOrder->VolumeTotal))
            {
                uint32_t deal_volume = entrust.last_volume - pOrder->VolumeTotal;
                entrust.last_volume = pOrder->VolumeTotal;

                // 触发成交事件
                this->fire_event(trader_event_type::TET_OrderDeal, estid, deal_volume, (uint32_t)(pOrder->VolumeTotal));
            }
            else
            {
                // 如果订单剩余量不正确，记录错误日志
                if (entrust.last_volume < static_cast<uint32_t>(pOrder->VolumeTotal))
                {
                    LOG_ERROR("OnRtnOrder Error", estid, code.get_id(), entrust.last_volume, pOrder->VolumeTotal);
                }
            }

            // 更新订单信息
            _order_info[estid] = entrust;
        }
    }
}



// ctp_api_trader::OnErrRtnOrderInsert() 方法
// 功能：处理订单插入（下单）错误通知的回调事件，当订单插入请求失败时被调用
// 参数：
// - pInputOrder: 指向订单插入请求信息结构体的指针，包含订单的详细信息
// - pRspInfo: 指向响应信息结构体的指针，包含错误代码和错误信息
// 返回值：无
void ctp_api_trader::OnErrRtnOrderInsert(CThostFtdcInputOrderField *pInputOrder, 
                                         CThostFtdcRspInfoField *pRspInfo) noexcept
{
    // 如果系统未初始化，直接返回
    if (!_is_inited)
    {
        return;
    }

    // 检查错误信息是否存在且存在错误代码
    if (pRspInfo && pRspInfo->ErrorID != 0)
    {
        // 记录错误日志，显示订单插入的错误代码和错误消息
        LOG_ERROR("OnErrRtnOrderInsert \tErrorID =", pRspInfo->ErrorID, " ErrorMsg =", pRspInfo->ErrorMsg);
    }

    // 如果订单信息和错误信息都存在
    if (pInputOrder && pRspInfo)
    {
        // 记录详细的错误日志，包括合约代码和原始订单数量
        LOG_ERROR("OnErrRtnOrderInsert", pInputOrder->InstrumentID, pInputOrder->VolumeTotalOriginal, pRspInfo->ErrorMsg);

        // 生成扩展订单 ID（estid），用于唯一标识订单
        estid_t estid = generate_estid(_front_id, _session_id, strtol(pInputOrder->OrderRef, NULL, 10));

        // 查找并删除错误订单信息
        auto it = _order_info.find(estid);
        if (it != _order_info.end())
        {
            _order_info.erase(it); // 删除订单信息
        }

        // 触发订单错误事件，通知系统发生下单错误
        this->fire_event(trader_event_type::TET_OrderError, // 事件类型：订单错误
                         error_type::ET_PLACE_ORDER,        // 错误类型：下单错误
                         estid,                             // 扩展订单 ID
                         (uint8_t)pRspInfo->ErrorID);       // 错误代码
    }
}

// ctp_api_trader::OnErrRtnOrderAction() 方法
// 功能：处理订单操作（如撤单）失败的回调事件，当订单操作请求失败时被调用
// 参数：
// - pOrderAction: 指向订单操作请求信息结构体的指针，包含订单操作的详细信息（如撤单请求）
// - pRspInfo: 指向响应信息结构体的指针，包含错误代码和错误信息
// 返回值：无
void ctp_api_trader::OnErrRtnOrderAction(CThostFtdcOrderActionField* pOrderAction, 
                                         CThostFtdcRspInfoField* pRspInfo) noexcept
{
    // 如果系统未初始化，直接返回
    if (!_is_inited)
    {
        return;
    }

    // 检查错误信息是否存在且存在错误代码
    if (pRspInfo && pRspInfo->ErrorID != 0)
    {
        // 记录错误日志，显示订单操作的错误代码和错误消息
        LOG_ERROR("OnErrRtnOrderAction \tErrorID = ", pRspInfo->ErrorID, " ErrorMsg =", pRspInfo->ErrorMsg);

        // 如果订单操作信息存在
        if (pOrderAction)
        {
            // 记录详细的错误日志，包括订单引用号、请求 ID、会话编号和前置编号
            LOG_ERROR("OnErrRtnOrderAction ", pOrderAction->OrderRef, pOrderAction->RequestID, pOrderAction->SessionID, pOrderAction->FrontID);

            // 生成扩展订单 ID（estid），用于唯一标识订单
            estid_t estid = generate_estid(pOrderAction->FrontID, pOrderAction->SessionID, strtol(pOrderAction->OrderRef, NULL, 10));

            // 触发订单错误事件，通知系统发生订单操作（如撤单）错误
            this->fire_event(trader_event_type::TET_OrderError, // 事件类型：订单错误
                             error_type::ET_CANCEL_ORDER,       // 错误类型：撤单错误
                             estid,                             // 扩展订单 ID
                             (uint8_t)pRspInfo->ErrorID);       // 错误代码
        }
    }
}


void ctp_api_trader::OnRtnInstrumentStatus(CThostFtdcInstrumentStatusField* pInstrumentStatus)noexcept
{
	
}

// ctp_api_trader::do_auth() 方法
// 功能：向 CTP 交易服务器发送认证请求，进行用户认证操作
// 返回值：如果认证请求发送成功返回 true，发送失败返回 false
bool ctp_api_trader::do_auth() noexcept
{
    // 检查交易 API 对象是否为空，如果为空则无法进行认证操作
    if (_td_api == nullptr)
    {
        return false; // 交易 API 未初始化，返回 false
    }

    // 定义认证请求结构体并初始化为 0
    CThostFtdcReqAuthenticateField req;
    memset(&req, 0, sizeof(req)); // 使用 memset 将结构体清零，确保字段初始值为 0

    // 设置认证请求的参数
    strcpy(req.BrokerID, _broker_id.c_str()); // 设置经纪商 ID
    strcpy(req.UserID, _userid.c_str());      // 设置用户 ID
    // strcpy(req.UserProductInfo, m_strProdInfo.c_str()); // 可选参数：用户产品信息，暂时注释掉
    strcpy(req.AuthCode, _authcode.c_str());  // 设置认证码
    strcpy(req.AppID, _appid.c_str());        // 设置应用 ID

    // 发送认证请求，调用交易 API 的 ReqAuthenticate 方法
    // 传入认证请求结构体和请求 ID
    int iResult = _td_api->ReqAuthenticate(&req, genreqid());

    // 检查请求结果，非 0 表示请求发送失败
    if (iResult != 0)
    {
        // 记录错误日志，显示认证请求失败的错误代码
        LOG_ERROR("ctp_api_trader do_auth request failed:", iResult);
        return false; // 返回 false，表示认证请求失败
    }

    return true; // 认证请求成功发送，返回 true
}


// ctp_api_trader::is_usable() 方法
// 功能：检查 CTP 交易 API 是否处于可用状态
// 返回值：如果交易 API 可用则返回 true，否则返回 false
bool ctp_api_trader::is_usable() const noexcept
{
    // 检查交易 API 对象是否为空，如果为空则表示不可用
    if (_td_api == nullptr)
    {
        return false; // 交易 API 未初始化或已释放，返回 false
    }

    // 检查系统是否已初始化，如果未初始化则表示不可用
    if (!_is_inited)
    {
        return false; // 系统尚未初始化，返回 false
    }

    // 返回当前的连接状态
    return _is_connected; // 只有在 API 已初始化且已连接时，才表示系统可用
}


// ctp_api_trader::place_order() 方法
// 功能：向 CTP 交易服务器发送下单请求
// 参数：
// - offset: 开平仓类型（如开仓、平仓）
// - direction: 买卖方向（如买入、卖出）
// - code: 交易合约代码和交易所代码
// - volume: 下单数量
// - price: 下单价格
// - flag: 订单类型标志（如普通、FAK、FOK）
// 返回值：返回下单生成的扩展订单 ID（estid），如果下单失败则返回 INVALID_ESTID
estid_t ctp_api_trader::place_order(offset_type offset, 
                                    direction_type direction, 
                                    const code_t& code, 
                                    uint32_t volume, 
                                    double_t price, 
                                    order_flag flag) noexcept
{
    // 开启性能调试信息
    PROFILE_DEBUG(code.get_id());
    // 记录下单信息日志，包括合约代码和下单数量
    LOG_INFO("ctp_api_trader place_order %s %d", code.get_id(), volume);

    // 检查交易 API 对象是否为空，如果为空则无法进行下单操作
    if (_td_api == nullptr)
    {
        return INVALID_ESTID; // 交易 API 未初始化，返回无效的订单 ID
    }

    // 生成扩展订单 ID（estid），用于唯一标识订单
    estid_t estid = generate_estid();

    // 定义订单请求结构体并初始化为 0
    CThostFtdcInputOrderField req;
    memset(&req, 0, sizeof(req)); // 将结构体清零，确保字段初始值为 0

    // 设置订单请求的基础参数
    strcpy(req.BrokerID, _broker_id.c_str());       // 设置经纪商 ID
    strcpy(req.InvestorID, _userid.c_str());        // 设置投资者 ID
    strcpy(req.InstrumentID, code.get_id());        // 设置合约代码
    strcpy(req.ExchangeID, code.get_excg());        // 设置交易所代码

    // 从扩展订单 ID 中提取前置编号、会话编号和订单引用号
    uint32_t order_ref = 0, session_id = 0, front_id = 0;
    extract_estid(estid, front_id, session_id, order_ref);
    // 设置订单引用号
    sprintf(req.OrderRef, "%u", order_ref);

    // 设置订单价格类型
    if (price != .0F)
    {
        // 限价单
        req.OrderPriceType = THOST_FTDC_OPT_LimitPrice;
    }
    else
    {
        // 市价单
        req.OrderPriceType = THOST_FTDC_OPT_BestPrice;
    }

    // 设置买卖方向
    req.Direction = convert_direction_offset(direction, offset);
    // 设置组合开平标志
    req.CombOffsetFlag[0] = convert_offset_type(code, volume, offset, direction);
    // 设置组合投机套保标志为投机
    req.CombHedgeFlag[0] = THOST_FTDC_HF_Speculation;
    // 设置订单价格
    req.LimitPrice = price;
    // 设置下单数量
    req.VolumeTotalOriginal = volume;

    // 根据订单类型设置不同的条件
    if (flag == order_flag::OF_NOR)
    {
        // 普通订单
        req.TimeCondition = THOST_FTDC_TC_GFD; // 当日有效
        req.VolumeCondition = THOST_FTDC_VC_AV; // 任意数量成交
        req.MinVolume = 1; // 最小成交量为 1
    }
    else if (flag == order_flag::OF_FAK)
    {
        // FAK（Fill and Kill）订单
        req.TimeCondition = THOST_FTDC_TC_IOC; // 立即成交否则撤销
        req.VolumeCondition = THOST_FTDC_VC_AV; // 任意数量成交
        req.MinVolume = 1; // 最小成交量为 1
    }
    else if (flag == order_flag::OF_FOK)
    {
        // FOK（Fill or Kill）订单
        req.TimeCondition = THOST_FTDC_TC_IOC; // 立即成交否则撤销
        req.VolumeCondition = THOST_FTDC_VC_CV; // 全部数量成交
        req.MinVolume = volume; // 最小成交量为下单数量
    }

    // 设置其他订单参数
    req.ContingentCondition = THOST_FTDC_CC_Immediately; // 触发条件为立即触发
    req.ForceCloseReason = THOST_FTDC_FCC_NotForceClose; // 非强平
    req.IsAutoSuspend = 0; // 不自动挂起
    req.UserForceClose = 0; // 不强平

    // 再次开启性能调试信息
    PROFILE_DEBUG(code.get_id());

    // 发送下单请求，调用交易 API 的 ReqOrderInsert 方法
    int iResult = _td_api->ReqOrderInsert(&req, genreqid());

    // 检查请求结果，非 0 表示请求发送失败
    if (iResult != 0)
    {
        // 记录错误日志，显示下单请求失败的错误代码
        LOG_ERROR("ctp_api_trader order_insert request failed: %d", iResult);
        return INVALID_ESTID; // 返回无效的订单 ID
    }

    // 记录性能信息
    PROFILE_INFO(code.get_id());
    return estid; // 返回生成的扩展订单 ID
}


// ctp_api_trader::cancel_order() 方法
// 功能：向 CTP 交易服务器发送撤单请求，尝试取消指定的订单
// 参数：
// - estid: 扩展订单 ID，用于唯一标识要撤销的订单
// 返回值：如果撤单请求发送成功返回 true，发送失败返回 false
bool ctp_api_trader::cancel_order(estid_t estid) noexcept
{
    // 检查交易 API 对象是否为空，如果为空则无法进行撤单操作
    if (_td_api == nullptr)
    {
        // 记录错误日志，显示订单 ID 以及 API 未初始化的信息
        LOG_ERROR("ctp_api_trader cancel_order _td_api nullptr : %llu", estid);
        return false; // 交易 API 未初始化，返回 false
    }

    // 查找指定的订单是否存在
    auto it = _order_info.find(estid);
    if (it == _order_info.end())
    {
        // 如果订单信息未找到，记录错误日志并返回 false
        LOG_ERROR("ctp_api_trader cancel_order order invalid : %llu", estid);
        return false; // 订单无效或不存在，返回 false
    }

    // 获取订单引用
    auto& order = it->second;
    uint32_t frontid = 0, sessionid = 0, orderref = 0;
    // 从扩展订单 ID 中提取前置编号、会话编号和订单引用号
    extract_estid(estid, frontid, sessionid, orderref);

    // 定义撤单请求结构体并初始化为 0
    CThostFtdcInputOrderActionField req;
    memset(&req, 0, sizeof(req)); // 将结构体清零，确保字段初始值为 0

    // 设置撤单请求的基础参数
    strcpy(req.BrokerID, _broker_id.c_str());      // 设置经纪商 ID
    strcpy(req.InvestorID, _userid.c_str());       // 设置投资者 ID
    strcpy(req.UserID, _userid.c_str());           // 设置用户 ID

    // 设置订单引用号
    sprintf(req.OrderRef, "%u", orderref);
    // 设置前置编号
    req.FrontID = frontid;
    // 设置会话编号
    req.SessionID = sessionid;
    // 设置操作标志为撤单
    req.ActionFlag = convert_action_flag(action_flag::AF_CANCEL);
    // 设置合约代码
    strcpy(req.InstrumentID, order.code.get_id());

    // 设置交易所代码
    strcpy(req.ExchangeID, order.code.get_excg());

    // 记录撤单请求的详细日志
    LOG_INFO("ctp_api_trader ReqOrderAction :", req.ExchangeID, req.InstrumentID, req.FrontID, req.SessionID, req.OrderRef, req.BrokerID, req.InvestorID, req.UserID, estid);

    // 发送撤单请求，调用交易 API 的 ReqOrderAction 方法
    int iResult = _td_api->ReqOrderAction(&req, genreqid());

    // 检查请求结果，非 0 表示请求发送失败
    if (iResult != 0)
    {
        // 记录错误日志，显示撤单请求失败的错误代码
        LOG_ERROR("ctp_api_trader order_action request failed:", iResult);
        return false; // 返回 false，表示撤单请求失败
    }

    return true; // 撤单请求成功发送，返回 true
}


// ctp_api_trader::get_trading_day() 方法
// 功能：获取当前的交易日
// 返回值：返回当前交易日的日期（格式为 uint32_t 类型的日期值）；如果无法获取交易日，则返回 0x0U
uint32_t ctp_api_trader::get_trading_day() const noexcept
{
    // 检查交易 API 对象是否存在
    if (_td_api)
    {
        // 调用交易 API 的 GetTradingDay 方法获取当前交易日，并转换为 uint32_t 类型
        return static_cast<uint32_t>(std::atoi(_td_api->GetTradingDay()));
    }
    // 如果交易 API 对象不存在，则返回 0x0U，表示无法获取交易日
    return 0X0U;
}



// ctp_api_trader::get_trader_data() 方法
// 功能：获取当前交易员的交易数据，包括订单和持仓信息
// 返回值：返回一个包含订单和持仓信息的 shared_ptr 指针对象，如果查询失败则返回包含空数据的对象
std::shared_ptr<trader_data> ctp_api_trader::get_trader_data() noexcept
{
    // 创建一个空的 trader_data 对象并用 shared_ptr 包装
    auto result = std::make_shared<trader_data>();

    // 查询持仓信息，传入 true 表示同步查询
    if (!query_positions(true))
    {
        // 如果查询持仓信息失败，记录错误日志并返回空的 trader_data 对象
        LOG_ERROR("query_positions error");
        return result;
    }

    // 等待一秒，以确保查询请求完成并处理数据（通常用于避免数据未处理完毕时读取）
    std::this_thread::sleep_for(std::chrono::seconds(1));

    // 查询订单信息，传入 true 表示同步查询
    if (!query_orders(true))
    {
        // 如果查询订单信息失败，记录错误日志并返回空的 trader_data 对象
        LOG_ERROR("query_orders error");
        return result;
    }

    // 遍历 _order_info 容器，将每个订单信息添加到 trader_data 的 orders 列表中
    for (auto it : _order_info)
    {
        result->orders.emplace_back(it.second);
    }

    // 遍历 _position_info 容器，将每个持仓信息添加到 trader_data 的 positions 列表中
    for (auto it : _position_info)
    {
        result->positions.emplace_back(it.second);
    }

    // 返回包含订单和持仓信息的 trader_data 对象
    return result;
}



// ctp_api_trader::submit_settlement() 方法
// 功能：向 CTP 交易服务器提交结算信息确认请求
// 返回值：无
void ctp_api_trader::submit_settlement() noexcept
{
    // 检查交易 API 对象是否为空，如果为空则无法进行结算确认操作
    if (_td_api == nullptr)
    {
        return; // 交易 API 未初始化，直接返回
    }

    // 定义结算信息确认请求结构体并初始化为 0
    CThostFtdcSettlementInfoConfirmField req;
    memset(&req, 0, sizeof(req)); // 将结构体清零，确保所有字段初始值为 0

    // 设置结算信息确认请求的参数
    strcpy(req.BrokerID, _broker_id.c_str()); // 设置经纪商 ID
    strcpy(req.InvestorID, _userid.c_str());  // 设置投资者 ID

    // 以下代码用于设置确认日期和时间，目前被注释掉
    // fmt::format_to(req.ConfirmDate, "{}", TimeUtils::getCurDate()); // 设置确认日期
    // memcpy(req.ConfirmTime, TimeUtils::getLocalTime().c_str(), 8);  // 设置确认时间

    // 发送结算信息确认请求，调用交易 API 的 ReqSettlementInfoConfirm 方法
    int iResult = _td_api->ReqSettlementInfoConfirm(&req, genreqid());

    // 检查请求结果，非 0 表示请求发送失败
    if (iResult != 0)
    {
        // 记录错误日志，显示结算确认请求失败的错误代码
        LOG_ERROR("ctp_api_trader submit_settlement request failed: %d", iResult);
    }

    // 设置同步等待标志为 true，表明正在等待服务器的响应
    while (!_is_sync_wait.exchange(true));

    // 等待服务器响应结算确认请求，使用条件变量等待，直到收到处理信号
    _process_signal.wait(_process_mutex);
}

